if not oUF then return end
if select(2, UnitClass("player")) ~= "ROGUE" and select(2, UnitClass("player")) ~= "DRUID" then return end

local GetTime = GetTime
local UnitMana = UnitMana
local UnitManaMax = UnitManaMax
local UnitPowerType = UnitPowerType
local UnitIsDeadOrGhost = UnitIsDeadOrGhost

local energy, lastEnergy, lastTick, tickTime, diff = UnitMana"player", UnitMana"player", GetTime(), 2, 0
local power, spark

local function shouldHide()
	if UnitPowerType"player" ~= 3 then
		return true
	elseif UnitIsDeadOrGhost"player" then
		return true
	elseif (energy == UnitManaMax"player" and (not UnitCanAttack("player", "target"))) then
		return true
	elseif (energy == UnitManaMax"player" and not UnitAffectingCombat"player") then
		return true
	else
		return false
	end
end

local function energyTicked(energy, lastEnergy)
	if (energy >= lastEnergy + 20 and energy < lastEnergy + 25) then
		return true
	elseif (energy >= lastEnergy + 40) then
		return true
	elseif (energy > lastEnergy and energy == UnitManaMax"player") then
		return true
	else
		return false
	end
end
	

local function onUpdate(self)
	energy = UnitMana"player"
	if shouldHide() then
		spark:Hide()
	else
		spark:Show()
	end
	
	diff = GetTime() - lastTick
	
	if energyTicked(energy, lastEnergy) or diff >= tickTime then
		lastTick = GetTime()
	end
	spark:SetPoint("CENTER", power, "LEFT", (diff / tickTime) * (power:GetWidth() - 1), 0)
	lastEnergy = energy
end

local function setUpdate(object)
	if object.Spark and object.unit == "player" then
		power = object.Power
		spark = object.Spark
		object:SetScript("OnUpdate", onUpdate)
	end
end

for object in pairs(oUF.objects) do setUpdate(object) end
oUF:RegisterInitCallback(setUpdate)